package cn.dota2info.elk.dao;

import cn.dota2info.elk.entity.BaseSearchParam;
import cn.dota2info.elk.entity.MatchSearchParam;
import cn.dota2info.elk.utils.MapUtils;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * elasticsearch search api操作
 *
 * @author wwmxd
 * @since 2018-07-10
 */
@Slf4j
@Repository
public class ElkSearchDao<T> {

    @Autowired
    private RestHighLevelClient client;

    private MapUtils<T> utils=new MapUtils<T>();

    /**
     * termQuery 输入的查询内容是什么，就会按照什么去查询，并不会解析查询内容，对它分词
     * @param index 索引
     * @param type  类型
     * @param param 基础查找实体类
     * @param c     封装实体class
     * @return
     * @throws Exception
     */
    public List<T> termQuery(String index, String type, BaseSearchParam param,Class c) throws Exception {
        SearchRequest searchRequest = new SearchRequest(index);
        searchRequest.types(type);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery(param.getName(),param.getSearchValue()));
        sourceBuilder.from(param.getCurrent()!=null?param.getCurrent():0);
        sourceBuilder.size(param.getSize()!=null?param.getSize():10);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest);
        return utils.hits2List(searchResponse.getHits(),c);
    }
    /**
     * matchQuery  搜索的时候，首先会解析查询字符串，进行分词，然后查询
     * @param index 索引
     * @param type  类型
     * @param param 查找实体类
     * @param c     封装实体class
     * @return
     * @throws Exception
     */
    public List<T> matchQuery(String index, String type, MatchSearchParam param, Class c) throws Exception {
        SearchRequest searchRequest = new SearchRequest(index);
        searchRequest.types(type);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(param.getName(), param.getSearchValue())
                .fuzziness(Fuzziness.AUTO)
                .prefixLength(param.getPrefixLength()!=null?param.getPrefixLength():3)
                .maxExpansions(param.getMaxExpansions()!=null?param.getMaxExpansions():10);
        sourceBuilder.query(matchQueryBuilder);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest);
        return utils.hits2List(searchResponse.getHits(),c);
    }

}
